{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Regression Example in Keras\n",
    "Predicting house prices in Boston, Massachusetts "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/the-deep-learners/deep-learning-illustrated/blob/master/notebooks/regression_in_keras.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Load dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from keras.datasets import boston_housing\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Dropout \n",
    "from keras.layers.normalization import BatchNormalization "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Load data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading data from https://s3.amazonaws.com/keras-datasets/boston_housing.npz\n",
      "57344/57026 [==============================] - 0s 1us/step\n"
     ]
    }
   ],
   "source": [
    "(X_train, y_train), (X_valid, y_valid) = boston_housing.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(404, 13)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(102, 13)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_valid.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  1.23247,   0.     ,   8.14   ,   0.     ,   0.538  ,   6.142  ,\n",
       "        91.7    ,   3.9769 ,   4.     , 307.     ,  21.     , 396.9    ,\n",
       "        18.72   ])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "15.2"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Design neural network architecture"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = Sequential()\n",
    "\n",
    "model.add(Dense(32, input_dim=13, activation='relu'))\n",
    "model.add(BatchNormalization())\n",
    "\n",
    "model.add(Dense(16, activation='relu'))\n",
    "model.add(BatchNormalization())\n",
    "model.add(Dropout(0.2))\n",
    "\n",
    "model.add(Dense(1, activation='linear'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_1 (Dense)              (None, 32)                448       \n",
      "_________________________________________________________________\n",
      "batch_normalization_1 (Batch (None, 32)                128       \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 16)                528       \n",
      "_________________________________________________________________\n",
      "batch_normalization_2 (Batch (None, 16)                64        \n",
      "_________________________________________________________________\n",
      "dropout_1 (Dropout)          (None, 16)                0         \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 1)                 17        \n",
      "=================================================================\n",
      "Total params: 1,185\n",
      "Trainable params: 1,089\n",
      "Non-trainable params: 96\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Configure Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(loss='mean_squared_error', optimizer='adam')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Train!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 404 samples, validate on 102 samples\n",
      "Epoch 1/32\n",
      "404/404 [==============================] - 0s 299us/step - loss: 49.2080 - val_loss: 56.6020\n",
      "Epoch 2/32\n",
      "404/404 [==============================] - 0s 271us/step - loss: 47.4038 - val_loss: 29.8796\n",
      "Epoch 3/32\n",
      "404/404 [==============================] - 0s 197us/step - loss: 46.7576 - val_loss: 23.9344\n",
      "Epoch 4/32\n",
      "404/404 [==============================] - 0s 187us/step - loss: 44.1485 - val_loss: 42.2967\n",
      "Epoch 5/32\n",
      "404/404 [==============================] - 0s 164us/step - loss: 49.0559 - val_loss: 46.9688\n",
      "Epoch 6/32\n",
      "404/404 [==============================] - 0s 162us/step - loss: 43.6892 - val_loss: 33.0174\n",
      "Epoch 7/32\n",
      "404/404 [==============================] - 0s 148us/step - loss: 47.0792 - val_loss: 54.1364\n",
      "Epoch 8/32\n",
      "404/404 [==============================] - 0s 153us/step - loss: 50.8361 - val_loss: 36.3195\n",
      "Epoch 9/32\n",
      "404/404 [==============================] - 0s 149us/step - loss: 40.6915 - val_loss: 29.8989\n",
      "Epoch 10/32\n",
      "404/404 [==============================] - 0s 148us/step - loss: 41.4807 - val_loss: 29.3190\n",
      "Epoch 11/32\n",
      "404/404 [==============================] - 0s 147us/step - loss: 51.2407 - val_loss: 40.1875\n",
      "Epoch 12/32\n",
      "404/404 [==============================] - 0s 147us/step - loss: 43.2374 - val_loss: 25.4212\n",
      "Epoch 13/32\n",
      "404/404 [==============================] - 0s 157us/step - loss: 43.1908 - val_loss: 29.2680\n",
      "Epoch 14/32\n",
      "404/404 [==============================] - 0s 158us/step - loss: 40.5124 - val_loss: 42.9114\n",
      "Epoch 15/32\n",
      "404/404 [==============================] - 0s 155us/step - loss: 40.9336 - val_loss: 30.4762\n",
      "Epoch 16/32\n",
      "404/404 [==============================] - 0s 150us/step - loss: 40.8193 - val_loss: 40.7844\n",
      "Epoch 17/32\n",
      "404/404 [==============================] - 0s 148us/step - loss: 39.6089 - val_loss: 34.6116\n",
      "Epoch 18/32\n",
      "404/404 [==============================] - 0s 151us/step - loss: 36.4934 - val_loss: 32.2122\n",
      "Epoch 19/32\n",
      "404/404 [==============================] - 0s 161us/step - loss: 34.1179 - val_loss: 34.0444\n",
      "Epoch 20/32\n",
      "404/404 [==============================] - 0s 163us/step - loss: 44.7315 - val_loss: 37.7222\n",
      "Epoch 21/32\n",
      "404/404 [==============================] - 0s 148us/step - loss: 41.5464 - val_loss: 30.2206\n",
      "Epoch 22/32\n",
      "404/404 [==============================] - 0s 152us/step - loss: 37.8592 - val_loss: 25.6582\n",
      "Epoch 23/32\n",
      "404/404 [==============================] - 0s 151us/step - loss: 38.6414 - val_loss: 35.0077\n",
      "Epoch 24/32\n",
      "404/404 [==============================] - 0s 150us/step - loss: 33.2319 - val_loss: 33.7788\n",
      "Epoch 25/32\n",
      "404/404 [==============================] - 0s 152us/step - loss: 40.1589 - val_loss: 35.2011\n",
      "Epoch 26/32\n",
      "404/404 [==============================] - 0s 148us/step - loss: 38.2410 - val_loss: 34.2764\n",
      "Epoch 27/32\n",
      "404/404 [==============================] - 0s 150us/step - loss: 43.7212 - val_loss: 53.3516\n",
      "Epoch 28/32\n",
      "404/404 [==============================] - 0s 154us/step - loss: 36.5388 - val_loss: 39.6444\n",
      "Epoch 29/32\n",
      "404/404 [==============================] - 0s 167us/step - loss: 45.9783 - val_loss: 34.5063\n",
      "Epoch 30/32\n",
      "404/404 [==============================] - 0s 155us/step - loss: 35.7326 - val_loss: 35.4458\n",
      "Epoch 31/32\n",
      "404/404 [==============================] - 0s 148us/step - loss: 35.9988 - val_loss: 28.6569\n",
      "Epoch 32/32\n",
      "404/404 [==============================] - 0s 150us/step - loss: 34.5900 - val_loss: 56.5418\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7f61e52a7128>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(X_train, y_train, \n",
    "          batch_size=8, epochs=32, verbose=1, \n",
    "          validation_data=(X_valid, y_valid))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  9.32909,   0.     ,  18.1    ,   0.     ,   0.713  ,   6.185  ,\n",
       "        98.7    ,   2.2616 ,  24.     , 666.     ,  20.2    , 396.9    ,\n",
       "        18.13   ])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_valid[42]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "14.1"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_valid[42]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[20.880333]], dtype=float32)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.predict(np.reshape(X_valid[42], [1, 13]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
